package com.zhiche.lisa.integration.inteface.otm;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.qiniu.storage.model.DefaultPutRet;
import com.zhiche.lisa.core.enums.IntegrationURIEnum;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.utils.XmlUtil;
import com.zhiche.lisa.core.utils.qiniu.util.QiniuUtils;
import com.zhiche.lisa.integration.dao.model.ImportLog;
import com.zhiche.lisa.integration.dao.model.ImportLogHistory;
import com.zhiche.lisa.integration.dto.huiyunche.HuiyuncheShipInfoDTO;
import com.zhiche.lisa.integration.dto.order.ShipmentDTO;
import com.zhiche.lisa.integration.service.IHuiyuncheService;
import com.zhiche.lisa.integration.service.IImportLogHistoryService;
import com.zhiche.lisa.integration.service.IImportLogService;
import com.zhiche.lisa.integration.service.IPushSubSystemService;
import com.zhiche.lisa.integration.surpports.enums.TableStatusEnum;
import org.dom4j.Document;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

/**
 * Created by zhaoguixin on 2018/7/21.
 */
@Service
public class OtmShipmentService {

    private Logger LOGGER = LoggerFactory.getLogger(getClass());

    @Autowired
    private IImportLogService importLogService;

    @Autowired
    private IImportLogHistoryService importLogHistoryService;

    @Autowired
    private IPushSubSystemService pushSubSystemService;

    @Autowired
    private IHuiyuncheService huiyuncheService;

    public ShipmentDTO otmShipmentImport(String shipmentXml) {
        Date startDate = new Date();
        String strData = shipmentXml.replaceAll(" xmlns=\"http://xmlns.oracle.com/apps/otm/transmission/v6.4\"", "")
                .replaceAll(" xmlns:gtm=\"http://xmlns.oracle.com/apps/gtm/transmission/v6.4\" " +
                        "xmlns:otm=\"http://xmlns.oracle.com/apps/otm/transmission/v6.4\"", "")
                .replaceAll(" xsi:type=\"otm:TransactionHeaderType\"", "").replaceAll("otm:", "");
        ShipmentDTO otmShipmentDTO = null;
        try {
            otmShipmentDTO = OtmShipmentParse.parse(strData);
            if (Objects.isNull(otmShipmentDTO)) throw new BaseException("OTM指令数据转换错误！");
        } catch (BaseException ex) {
            throw ex;
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }

        pushShipToSubSystem(otmShipmentDTO,startDate,shipmentXml);

        return otmShipmentDTO;
    }

    /**
     * 指令推送子系统
     */
    private void pushShipToSubSystem(ShipmentDTO otmShipmentDTO,Date startDate,String shipmentXml) {
        new Thread(() -> {
            LOGGER.info("开始保存导入日志---------------");
            try {
                pushSubSystemService.saveShipmentLog(otmShipmentDTO, IntegrationURIEnum.SHIPMENT_PUSH.getCode(),startDate,shipmentXml,otmShipmentDTO.getShipmentId(),otmShipmentDTO.getSenderTransmissionNo());
//                pushSubSystemService.pushToSubSystemNew(otmShipmentDTO, IntegrationURIEnum.SHIPMENT_PUSH.getCode(),startDate,shipmentXml,otmShipmentDTO.getShipmentId(),otmShipmentDTO.getSenderTransmissionNo());
            } catch (Exception ex) {
                LOGGER.info(ex.getMessage());
            }
            LOGGER.info("完成日志保存---------------");
        }).start();
    }

    public ShipmentDTO getOtmShipmentById(String shipmentId) throws Exception {
//        Wrapper<ImportLog> ew = new EntityWrapper<>();
//        ew.eq("source_sys", "otm");
//        ew.eq("source_key", shipmentId);
//        ew.eq("type", IntegrationURIEnum.SHIPMENT_PUSH.getCode());
//        ImportLog importLog = importLogService.selectOne(ew);
//        if (Objects.isNull(importLog)) return null;
//
//        String qiniuKey = importLog.getDataStorageKey();
//        String downloadUrl = QiniuUtils.getDownloadUrl(qiniuKey);
//        String shipmentXml = readFile(downloadUrl);
//
//        String strData = shipmentXml.replaceAll(" xmlns=\"http://xmlns.oracle.com/apps/otm/transmission/v6.4\"", "")
//                .replaceAll(" xmlns:gtm=\"http://xmlns.oracle.com/apps/gtm/transmission/v6.4\" " +
//                        "xmlns:otm=\"http://xmlns.oracle.com/apps/otm/transmission/v6.4\"", "")
//                .replaceAll(" xsi:type=\"otm:TransactionHeaderType\"", "").replaceAll("otm:", "");
//        ShipmentDTO otmShipmentDTO;
//        try {
//            otmShipmentDTO = OtmShipmentParse.parse(strData);
//            if (Objects.isNull(otmShipmentDTO)) throw new BaseException("OTM指令数据转换错误！");
//        } catch (BaseException ex) {
//            throw ex;
//        } catch (Exception e) {
//            throw new BaseException(e.getMessage());
//        }
//        return otmShipmentDTO;
        ShipmentDTO otmShipmentDTO = new ShipmentDTO();
        try {
            Wrapper<ImportLog> ew = new EntityWrapper<>();
            ew.eq("source_sys", "otm");
            ew.eq("source_key", shipmentId);
            ew.eq("type", IntegrationURIEnum.SHIPMENT_PUSH.getCode());
            // huangzhigang 20190917 add -------- start
            ew.orderBy("id", false);
            // huangzhigang 20190917 add -------- end
            ImportLog importLog = importLogService.selectOne(ew);
            if (Objects.isNull(importLog)) throw new BaseException("未查询到数据！");
            String qiniuKey = importLog.getDataStorageKey();
            String downloadUrl = QiniuUtils.getDownloadUrl(qiniuKey);
            String shipmentXml = readFile(downloadUrl);
            String strData = shipmentXml.replaceAll(" xmlns=\"http://xmlns.oracle.com/apps/otm/transmission/v6.4\"", "")
                    .replaceAll(" xmlns:gtm=\"http://xmlns.oracle.com/apps/gtm/transmission/v6.4\" " +
                            "xmlns:otm=\"http://xmlns.oracle.com/apps/otm/transmission/v6.4\"", "")
                    .replaceAll(" xsi:type=\"otm:TransactionHeaderType\"", "").replaceAll("otm:", "");
            otmShipmentDTO = OtmShipmentParse.parse(strData);
         if (Objects.isNull(otmShipmentDTO)) throw new BaseException("OTM指令数据转换错误！");
        } catch (BaseException ex) {
            LOGGER.error(ex.getMessage());
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
            throw new BaseException(e.getMessage());
        }
        return otmShipmentDTO;
    }

    private String readFile(String fileUrl) {
        int HttpResult; // 服务器返回的状态
        String fileContent = new String();
        try {
            URL url = new URL(fileUrl); // 创建URL
            URLConnection urlconn = url.openConnection(); // 试图连接并取得返回状态码
            urlconn.connect();
            HttpURLConnection httpconn = (HttpURLConnection) urlconn;
            HttpResult = httpconn.getResponseCode();
            if (HttpResult != HttpURLConnection.HTTP_OK) {
                LOGGER.info("无法连接到文件地址");
            } else {
//                int filesize = urlconn.getContentLength(); // 取数据长度
                InputStreamReader isReader = new InputStreamReader(urlconn.getInputStream(), "UTF-8");
                BufferedReader reader = new BufferedReader(isReader);
                StringBuffer buffer = new StringBuffer();
                String line; // 用来保存每行读取的内容
                line = reader.readLine(); // 读取第一行
                while (line != null) { // 如果 line 为空说明读完了
                    buffer.append(line); // 将读到的内容添加到 buffer 中
                    buffer.append(" "); // 添加换行符
                    line = reader.readLine(); // 读取下一行
                }
                System.out.print(buffer.toString());
                fileContent = buffer.toString();
            }
        } catch (FileNotFoundException e) {
            LOGGER.info(e.getMessage());
        } catch (IOException e) {
            LOGGER.info(e.getMessage());
        }
        return fileContent;
    }


    /**
     * 保存日志历史和数据内容
     */
    public void updateLogHistory(ImportLogHistory importLogHistory, String dataContent) {
        String qiniuKey;
        try {
            Wrapper<ImportLog> ew = new EntityWrapper<>();
            ew.eq("source_sys", importLogHistory.getSourceSys());
            ew.eq("source_key", importLogHistory.getSourceKey());
            ew.eq("type", importLogHistory.getType());
            ImportLog importLog = importLogService.selectOne(ew);
            if (Objects.nonNull(importLog)) {
                Integer logId = importLog.getId();
                BeanUtils.copyProperties(importLogHistory, importLog);
                importLogHistory.setLogId(logId);
                importLog.setId(logId);
                importLog.setGmtCreate(null);
                importLog.setGmtModified(null);
                importLogHistoryService.insert(importLogHistory);
                importLogService.updateById(importLog);
            } else {
                importLog = new ImportLog();
                BeanUtils.copyProperties(importLogHistory, importLog);
                importLogService.insert(importLog);
                importLogHistory.setLogId(importLog.getId());
                importLogHistoryService.insert(importLogHistory);
            }

            String fileName = importLogHistory.getSourceSys() + "_" + importLogHistory.getType() + "_" +
                    importLogHistory.getSourceKey() + "_" + importLogHistory.getLogId() + "_" + importLogHistory.getId();
            DefaultPutRet putRet = QiniuUtils.uploadString(dataContent, fileName);
            qiniuKey = putRet.key;
            importLogHistory.setDataStorageKey(qiniuKey);
            importLogHistoryService.updateById(importLogHistory);

//            importLog.setDataStorageKey(qiniuKey);
//            importLogService.updateById(importLog);
            updateLog(importLogHistory, importLog);

        } catch (Exception ex) {
            LOGGER.info(ex.getMessage());
        }
    }

    /**
     * 更新ImportLog中的七牛key
     * @param importLogHistory
     * @param importLog
     */
    private void updateLog(ImportLogHistory importLogHistory, ImportLog importLog) {
        //取最新一条指令的日志记录
        Wrapper<ImportLogHistory> ew = new EntityWrapper<>();
        ew.eq("log_id", importLogHistory.getLogId());
        ew.eq("source_sys", importLogHistory.getSourceSys());
        ew.eq("target_sys", importLogHistory.getTargetSys());
        ew.eq("source_key", importLogHistory.getSourceKey());
        ew.eq("type", importLogHistory.getType());
        ew.orderBy("transmission_no", false);
        ImportLogHistory logHistory = importLogHistoryService.selectOne(ew);

        importLog.setDataStorageKey(logHistory.getDataStorageKey());
        importLogService.updateById(importLog);
    }

    public ShipmentDTO otmEmptyOrderImport(String xml) throws Exception {
        Date startDate = new Date();
        Document document = XmlUtil.parseByString(xml);
        Element re = document.getRootElement();
        Element srE = re.element("shipment_returnQuery");
        ShipmentDTO dto = new ShipmentDTO();
        if (srE != null) {
            shipmentParse(srE, dto);
        }
        // 目前写死数据处理方式
        dto.setTransactionCode("IU");
//        Date endDate = new Date();
//        ImportLogHistory importLogHistory = new ImportLogHistory();
//        importLogHistory.setSourceSys("otm");
//        importLogHistory.setSourceKey(dto.getShipmentId());
//        importLogHistory.setType(IntegrationURIEnum.EMPTY_SHIPMENT_PUSH.getCode());
//        importLogHistory.setImportStartTime(startDate);
//        importLogHistory.setImportEndTime(endDate);
////        new Thread(() -> {
//        LOGGER.info("开始保存导入日志---------------");
//        updateLogHistory(importLogHistory, xml);
//        LOGGER.info("完成日志保存---------------");
//        }).start();
        pushEmptyShipToSubSystem(dto,startDate,xml);
        return dto;
    }

    private void shipmentParse(Element srE, ShipmentDTO dto) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Element d_loc_zone1 = srE.element("d_loc_zone1");//启运地省
        if (d_loc_zone1 != null) {
            dto.setDestLocationProvince(d_loc_zone1.getText());
        }
        Element d_loc_zone2 = srE.element("d_loc_zone2");
        if (d_loc_zone2 != null) {
            dto.setDestLocationCity(d_loc_zone2.getText());
        }
        Element d_loc_zone3 = srE.element("d_loc_zone3");
        if (d_loc_zone3 != null) {
            dto.setDestLocationCounty(d_loc_zone3.getText());
        }
        Element d_loc_location_name = srE.element("d_loc_location_name");
        if (d_loc_location_name != null) {
            dto.setDestLocationName(d_loc_location_name.getText());
        }
        Element d_loc_location_gid = srE.element("d_loc_location_gid");//启运地标识
        if (d_loc_location_gid != null) {
            if (d_loc_location_gid.getText().startsWith("ULC/ZC.")) {
                dto.setDestLocationId(d_loc_location_gid.getText().replaceAll("ULC/ZC.", ""));
            } else {
                dto.setDestLocationId(d_loc_location_gid.getText());
            }
        }
        Element servprov_name = srE.element("servprov_name");//承运商
        if (servprov_name != null) {
            dto.setServiceProviderName(servprov_name.getText());
        }
        //Element attribute10 = srE.element("attribute10");//车队
        //if (attribute10 != null) {
        //    dto.set
        //}
        Element attribute12 = srE.element("attribute12");//车牌
        if (attribute12 != null) {
            dto.setPlateNo(attribute12.getText());
        }
        Element attribute1 = srE.element("attribute1");//指令类型
        if (attribute1 != null) {
            if (attribute1.getText().startsWith("ULC/ZC.")) {
                dto.setShipmentType(attribute1.getText().replaceAll("ULC/ZC.", ""));
            } else {
                dto.setShipmentType(attribute1.getText());
            }
        }
        Element transport_type = srE.element("transport_type");//运输方式
        if (transport_type != null) {
            dto.setTransportModeId(transport_type.getText());
        }
        Element attribute7 = srE.element("attribute7");//司机名
        if (attribute7 != null) {
            dto.setDriverName(attribute7.getText());
        }
        Element attribute19 = srE.element("attribute19");//空放类型
        if (attribute19 != null) {
            dto.setEmptyType(attribute19.getText());
        }
        Element s_loc_location_gid = srE.element("s_loc_location_gid");
        if (s_loc_location_gid != null) {
            if (s_loc_location_gid.getText().startsWith("ULC/ZC.")) {
                dto.setOriginLocationId(s_loc_location_gid.getText().replaceAll("ULC/ZC.", ""));
            } else {
                dto.setOriginLocationId(s_loc_location_gid.getText());
            }
        }
        Element s_loc_zone1 = srE.element("s_loc_zone1");//目的地-省
        if (s_loc_zone1 != null) {
            dto.setOriginLocationProvince(s_loc_zone1.getText());
        }
        Element s_loc_zone2 = srE.element("s_loc_zone2");//目的地-市
        if (s_loc_zone2 != null) {
            dto.setOriginLocationCity(s_loc_zone2.getText());
        }
        Element s_loc_zone3 = srE.element("s_loc_zone3");//目的地-区
        if (s_loc_zone3 != null) {
            dto.setOriginLocationCounty(s_loc_zone3.getText());
        }
        Element shipment_xid = srE.element("shipment_xid");//指令号
        if (shipment_xid != null) {
            dto.setShipmentId(shipment_xid.getText());
        }
        Element s_loc_location_name = srE.element("s_loc_location_name");
        if (s_loc_location_name != null) {
            dto.setOriginLocationName(s_loc_location_name.getText());
        }
        Element servprov_gid = srE.element("servprov_gid");//承运商id
        if (servprov_gid != null) {
            if (servprov_gid.getText().startsWith("ULC/ZC.")) {
                dto.setServiceProviderId(servprov_gid.getText().replaceAll("ULC/ZC.", ""));
            } else {
                dto.setServiceProviderId(servprov_gid.getText());
            }
        }
        Element insert_date = srE.element("insert_date");//调度时间
        if (insert_date != null) {
            try {
                dto.setInsertDate(formatter.parse(insert_date.getText()));
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 空放指令推送子系统
     */
    private void pushEmptyShipToSubSystem(ShipmentDTO otmShipmentDTO,Date startDate,String shipmentXml) {
        LOGGER.info("开始保存导入日志---------------");
        try {
            pushSubSystemService.pushToSubSystemNew(otmShipmentDTO, IntegrationURIEnum.EMPTY_SHIPMENT_PUSH.getCode(),startDate,shipmentXml,otmShipmentDTO.getShipmentId(),otmShipmentDTO.getSenderTransmissionNo());
        } catch (Exception ex) {
            LOGGER.info(ex.getMessage());
        }
        LOGGER.info("完成日志保存---------------");
    }

    public ShipmentDTO getEmptyShipmentById(String shipmentId) throws Exception {
        Wrapper<ImportLog> ew = new EntityWrapper<>();
        ew.eq("source_sys", "otm");
        ew.eq("source_key", shipmentId);
        ew.eq("type", IntegrationURIEnum.EMPTY_SHIPMENT_PUSH.getCode());
        ImportLog importLog = importLogService.selectOne(ew);
        if (Objects.isNull(importLog)) return null;

        String qiniuKey = importLog.getDataStorageKey();
        String downloadUrl = QiniuUtils.getDownloadUrl(qiniuKey);
        String shipmentXml = readFile(downloadUrl);
        Document document = XmlUtil.parseByString(shipmentXml);
        Element re = document.getRootElement();
        Element srE = re.element("shipment_returnQuery");
        ShipmentDTO dto = new ShipmentDTO();
        if (srE != null) {
            shipmentParse(srE, dto);
        }
        // 目前写死数据处理方式
        dto.setTransactionCode("IU");
        return dto;
    }

    public String getEmptyStringXML(String shipmentId){
        Wrapper<ImportLog> ew = new EntityWrapper<>();
        ew.eq("source_sys", "otm");
        ew.eq("source_key", shipmentId);
        ew.eq("type", IntegrationURIEnum.EMPTY_SHIPMENT_PUSH.getCode());
        ImportLog importLog = importLogService.selectOne(ew);
        if (Objects.isNull(importLog)) return null;

        String qiniuKey = importLog.getDataStorageKey();
        String downloadUrl = QiniuUtils.getDownloadUrl(qiniuKey);
        String shipmentXml = readFile(downloadUrl);
        return shipmentXml;
    }

    public HuiyuncheShipInfoDTO getHuiyuncheShipmentById(String shipmentId) {
        String[] split = shipmentId.split(",");
        for (String s : split) {
            Wrapper<ImportLog> ew = new EntityWrapper<>();
            ew.eq("source_sys", "huiyunche");
            ew.eq("source_key", s.trim().replace("\n", ""));
            ew.eq("type", TableStatusEnum.STATUS_11.getCode());
            ImportLog importLog = importLogService.selectOne(ew);
            if (Objects.isNull(importLog)) continue;
            String qiniuKey = importLog.getDataStorageKey();
            String downloadUrl = QiniuUtils.getDownloadUrl(qiniuKey);
            String shipmentXml = readFile(downloadUrl);
            HuiyuncheShipInfoDTO huiyuncheShipInfoDTO = JSONObject.parseObject(shipmentXml, HuiyuncheShipInfoDTO.class);
            huiyuncheService.importShipment(huiyuncheShipInfoDTO);
        }
        return null;
    }

    public String getOrderStringXML(String shipmentId){
        Wrapper<ImportLog> ew = new EntityWrapper<>();
        ew.eq("source_sys", "otm");
        ew.eq("source_key", shipmentId);
        ew.eq("type", IntegrationURIEnum.SHIPMENT_PUSH.getCode());
        ImportLog importLog = importLogService.selectOne(ew);
        if (Objects.isNull(importLog)) return null;

        String qiniuKey = importLog.getDataStorageKey();
        String downloadUrl = QiniuUtils.getDownloadUrl(qiniuKey);
        String shipmentXml = readFile(downloadUrl);
        return shipmentXml;
    }

    public String getOrderStringXMLByKey(String qiniuKey){
        String downloadUrl = QiniuUtils.getDownloadUrl(qiniuKey);
        String shipmentXml = readFile(downloadUrl);
        return shipmentXml;
    }
}



